該文章同步發佈於:我的部落格
也歡迎關注我的 Facebook 以及 Instagram 接收軟體相關的資訊!
經過了前幾篇文章的洗禮,現在對於 Elasticsearch ( 以下簡稱 ES ) 應該有了更深的理解,但在開始介紹搜尋之前,需要先介紹 ES 中的 Analyzer 是什麼,以及它怎麼作用。
因為這和搜尋息息相關,所以必須要有基本的認知。
在我們建立一個 index 的時候,ES 會採用一種叫做 dynamic mapping 的方式來檢查每一個儲存的字串,什麼意思呢?
Dynamice Mapping 參考連結
{
"name": "Robert Chang" // ES 會動態地認為這是 text
}
{
"uuid": "a6d30daf-d0ba-4221-816b-802c0fe37bcc" // ES 會動態地認為這是 keyword
}
而當這個值被認為是 text 時,就會經過 analyzer 處理,接著被以 Inverted index 的方式儲存,這邊不介紹 Inverted index 是什麼,有興趣可以自己理解一下,但這就是為什麼 ES 可以這麼快地進行全文搜尋的原因。
等等,所以 ES 不是搜尋我們看到的 _source
裡面的字串嗎?是的,ES 並不是這樣做,這麼做的效率太低了。
Analyzer 可以分成三大組件,如下圖所示:
讓我們依序來介紹一下
這個階段主要是處理原始的資料,可以用來消除或是替換掉特定的文字,而且這個 character filter 是可以替換的,也就是可以根據我們想要 filter 的資料做特殊處理。
舉例來說,使用 html_strip
這個 filter。
它會把:
My <em>name</em> is <strong> Robert</strong>
變成:
My name is Robert
或是使用 Mapping character filter,並針對特殊的字串進行設定,像是 a=1, b=2, ..etc 這樣。
可以把:
"abcd"
變成:
"1234"
接著第一階段就完成了,把原始的文字資料進行清洗和篩選,接著會變成 Tokenizer 的任務。
這和 character filter 很像,一樣可以套用很多不一樣的設定,但最基本的就是 Standard Tokenizer,也就是根據空格以及標點符號把文字拆解成多個 token。
token 這個字因為 AI 現在很紅,但其實可以想像一個 token 就是一個詞彙的概念
所以繼續拿上面的當作例子,被 filter 完的文字會變成 My name is Robert。
經過 Standard Tokenizer 的處理後,會變成這樣:
["My", "name", "is", "Robert"]
還有很多很有趣的 tokenizer,都是取決於專案要怎麼處理文字資料等等的需求而選擇,Tokenizer
好的,拆解成一個個 token 之後呢?要把資料遞交給 Token Filter 來處理最後的步驟。
蛤?啊資料都被你拆成 token 了,你還想要怎麼樣?當然就是因為 token 並不是每一個都有意義,也不是每一個都符合需求,我們還需要在更進一步的來處理這些 token,讓它變成值得參考的資料。
如同前兩個組件一樣,token filter 也有很多不同的選擇可以參考,但不外乎都是要針對每一個 token 來處理。
一樣把 ["My", "name", "is", "Robert"] 傳遞到 token filter,並套上 Lowercase token filter 處理。
結果會變成:
["my", "name", "is", "robert"]
像我就有看到一個很有趣的 token filter,叫做 Stopwords Token Filter,可以把移除掉比較沒有意義的 token。
舉例:
["You", "are", "the", "best"]
變成:
["You", "are", "best"]
拿掉 the
這種比較沒有意義的詞彙。
OK,以這整個流程來說,最後就會得到 ["my", "name", "is", "robert"]
的值,接著就是把這個分析後的 token 們以 Inverted index 的方式儲存起來。
那這就是 ES 的 analyzer 在做的事情,analyzer 本身是一個大型的工廠,裏面則有很多的零組件可以進行替換,來根據需求處理不同格式的資料,最終產出符合需求的資料。
有趣吧!?我一開始也以為 ES 會是在 _source
裡面搜尋,像是關聯式資料庫一樣,但果然能做出這種產品的人,想得一定和我不一樣,快學起來!